home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 41
/
Amiga Format CD41 (1999-06)(Future Publishing)(GB)[!][issue 1999-07].iso
/
-seriously_amiga-
/
graphics
/
mountainview
/
gui.c
next >
Wrap
C/C++ Source or Header
|
1999-04-28
|
25KB
|
740 lines
/*========================================================================*\
| File: gui.c Date: 23 Jan 1999 |
*------------------------------------------------------------------------*
| Creates windows and requesters, all this stuff that requires |
| filling in huge structs and arrays. Doesn't do any input processing, |
| except for some requester-like functions. |
| |
\*========================================================================*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <proto/gadtools.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <proto/asl.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/wb.h>
#include <proto/icon.h>
#include <graphics/gfxbase.h>
#include <intuition/gadgetclass.h>
#include "gui.h"
/* Simplified version information that controls some of our features. */
BOOL fGTV39 = FALSE;
BOOL fIntV39 = FALSE;
BOOL fGfxV39 = FALSE;
/* Define and nullify the libbases, so libnix doesn't auto-open them. */
struct GfxBase *GfxBase = NULL;
struct IntuitionBase *IntuitionBase = NULL;
struct Library *GadToolsBase = NULL;
struct Library *AslBase = NULL;
enum {
MSRT_STRING = 0,
MSRT_LONG,
MSRT_FLOAT
};
typedef struct /* Describe one line in a MultiStringRequest(). */
{
STRPTR strLabel; /* label in front of this string gadget */
WORD wType; /* one of the above MSRT_XXX-constants */
union {
STRPTR strBuf;
LONG lVal;
FLOAT flVal;
} val;
WORD wBufSize; /* only needed with MSRT_STRING */
struct Gadget *pgad; /* for internal purposes */
} MSR_ITEM;
struct Window *pwinMain = NULL;
struct Menu *menu = NULL;
struct Screen *scr = NULL;
APTR visualInfo = NULL;
struct TextFont *defFont = NULL;
struct TextAttr defFontA;
LONG laPens[ 32 ];
/* Propgadgets, must be plain intuition (no gadtools) gadgets. */
struct Image imgRise, imgSpin;
struct PropInfo piRise =
{
AUTOKNOB | PROPNEWLOOK | FREEVERT,
MAXPOT, MAXPOT / 2, /* start at 45° */
MAXBODY, MAXBODY / 10 /* 0 - 90° at 10° granularity */
};
struct PropInfo piSpin =
{
AUTOKNOB | PROPNEWLOOK | FREEHORIZ,
MAXPOT / 12 * 5, MAXPOT, /* start at 150° */
MAXBODY / 13, MAXBODY /* 0 - 360° at 30° granularity */
};
struct Gadget gadRise =
{
NULL, /* no link */
0, 0, 0, 0, /* we'll fill in the dimensions later */
GFLG_RELHEIGHT | GFLG_RELRIGHT,
GACT_RELVERIFY | GACT_IMMEDIATE | GACT_RIGHTBORDER,
GTYP_PROPGADGET,
&imgRise, NULL, NULL, 0,
&piRise, IDC_HEIGHT, NULL
};
struct Gadget gadSpin =
{
NULL,
0, 0, 0, 0,
GFLG_RELWIDTH | GFLG_RELBOTTOM,
GACT_RELVERIFY | GACT_IMMEDIATE | GACT_BOTTOMBORDER,
GTYP_PROPGADGET,
&imgSpin, NULL, NULL, 0,
&piSpin, IDC_ROTATION, NULL
};
/* Oh, and one button gadget. */
struct Gadget gadCmd =
{
NULL,
0, 0, 0, 0,
GFLG_GADGHCOMP | GFLG_RELRIGHT,
GACT_RELVERIFY | GACT_RIGHTBORDER,
GTYP_BOOLGADGET,
/*border*/NULL, NULL, NULL, 0,
NULL, IDC_STOP_GO, NULL
};
#define AREA_BYTES 100 /* small buffer for simple area fills */
WORD waArBuf[ AREA_BYTES/2 ];
struct AreaInfo ari;
struct TmpRas tras;
void *ras;
WORD wMaxX, wMaxY; /* we'll allocate a raster of this size */
#define FNAME_SIZE 40 /* only for the file part of a path name */
/* Shortcut, so the flags don't clutter the layout of the menu table. */
#define CM CHECKIT | MENUTOGGLE
struct NewMenu nmaMenu[] =
{
{ NM_TITLE, "Mountain", NULL, 0, 0, NULL },
{ NM_ITEM, "New map", "N", 0, 0, (APTR)IDM_NEW },
{ NM_ITEM, "Border", "B", CM, 0, (APTR)IDM_BORDER },
{ NM_ITEM, "Auto redraw", "A", CM, 0, (APTR)IDM_AUTODRAW },
{ NM_ITEM, "Draw", "D", 0, 0, (APTR)IDM_DRAW },
{ NM_ITEM, "Stop drawing", "X", 0, 0, (APTR)IDM_ABORT },
{ NM_ITEM, NM_BARLABEL, NULL, 0, 0, NULL },
{ NM_ITEM, "Quit", "Q", 0, 0, (APTR)IDM_QUIT },
{ NM_TITLE, "Window", NULL, 0, 0, NULL },
{ NM_ITEM, "Maximize", "M", 0, 0, (APTR)IDM_MAX },
{ NM_ITEM, "Center", "C", 0, 0, (APTR)IDM_CENTER },
{ NM_ITEM, "Zoom", "Z", 0, 0, (APTR)IDM_ZOOM },
{ NM_END, NULL, NULL, 0, 0, NULL }
};
#undef CM
/*------------------------------------------------------------------------*\
This is called upon exit and closes libraries and such stuff.
Zeroes all its pointers, so it can be safely called more than once.
\*------------------------------------------------------------------------*/
VOID LibClose( struct Library **ppLib )
{
if( *ppLib )
{
CloseLibrary( *ppLib );
*ppLib = NULL;
}
}
VOID GetMeOutOfHere()
{
LibClose( (struct Library **)&IntuitionBase );
LibClose( (struct Library **)&GfxBase );
LibClose( &GadToolsBase );
LibClose( &AslBase );
}
/*------------------------------------------------------------------------*\
Allocate all needed system resources and install a cleanup routine
to close them at exit.
\*------------------------------------------------------------------------*/
BOOL StartMeUp()
{
BOOL fDOSV36;
IntuitionBase = (struct IntuitionBase*)OpenLibrary( "intuition.library", 0 );
GfxBase = (struct GfxBase*)OpenLibrary( "graphics.library", 0 );
GadToolsBase = OpenLibrary( "gadtools.library", 0 );
AslBase = OpenLibrary( "asl.library", 0 );
/* Extract version information. */
fDOSV36 = (DOSBase && ((struct Library*)DOSBase)->lib_Version >= 36);
fIntV39 = (IntuitionBase && ((struct Library*)IntuitionBase)->lib_Version >= 39);
fGfxV39 = (GfxBase && ((struct Library*)GfxBase)->lib_Version >= 39);
fGTV39 = (GadToolsBase && GadToolsBase->lib_Version >= 39);
/* Some allocations may fail, but others must not, */
/* and while we can rely on the standard startup code to have opened */
/* dos.library for us, we must insist that it's V36+. */
return( fDOSV36 && IntuitionBase && GfxBase && GadToolsBase );
}
/*------------------------------------------------------------------------*\
Set up the window.
\*------------------------------------------------------------------------*/
BOOL BuildGui()
{
WORD wIdx;
LONG lScrTag;
struct ColorSpec csa[ 33 ];
if( fGfxV39 )
{ /* use pen sharing with OS 3.x */
scr = LockPubScreen( NULL );
if( !scr )
goto fail;
lScrTag = WA_PubScreen;
for( wIdx = 0; wIdx < 16; wIdx++ )
laPens[ wIdx ] = ObtainBestPen( scr->ViewPort.ColorMap,
wIdx * 0x10000000,
wIdx * 0x0A000000,
wIdx * 0x05000000,
TAG_DONE ); /* shades of brown */
laPens[ 16 ] = ObtainBestPen( scr->ViewPort.ColorMap,
0x00000000,
0x40000000,
0x80000000,
TAG_DONE ); /* blue */
for( wIdx = 1; wIdx < 16; wIdx++ )
laPens[ wIdx + 16 ] = ObtainBestPen( scr->ViewPort.ColorMap,
wIdx * 0x10000000,
wIdx * 0x10000000,
wIdx * 0x10000000,
TAG_DONE ); /* shades of gray */
}
else
{ /* else open an own screen */
for( wIdx = 0; wIdx < 16; wIdx++ )
{
csa[ wIdx ].ColorIndex = wIdx;
csa[ wIdx ].Red = wIdx;
csa[ wIdx ].Green = (10 * wIdx)/16;
csa[ wIdx ].Blue = (5 * wIdx)/16;
} /* shades of brown */
csa[ 16 ].ColorIndex = 16;
csa[ 16 ].Red = 0;
csa[ 16 ].Green = 4;
csa[ 16 ].Blue = 8; /* blue */
for( wIdx = 17; wIdx < 32; wIdx++ )
{
csa[ wIdx ].ColorIndex = wIdx;
csa[ wIdx ].Red = wIdx - 16;
csa[ wIdx ].Green = wIdx - 16;
csa[ wIdx ].Blue = wIdx - 16;
} /* shades of gray */
csa[ 32 ].ColorIndex = -1;
/* Rearrange some colors, so that we start with gray, black, */
/* white and blue (which are currently at 24, 0, 31, 16) */
/* and set up brown, dark gray and light gray (8, 18, 28) for */
/* the cursor sprite (palette colors 17 through 19). */
csa[ 24 ].ColorIndex = 0;
csa[ 0 ].ColorIndex = 1;
csa[ 31 ].ColorIndex = 2;
csa[ 16 ].ColorIndex = 3;
csa[ 8 ].ColorIndex = 17;
csa[ 28 ].ColorIndex = 19;
/* Put the palette back in balance. */
csa[ 1 ].ColorIndex = 8;
csa[ 2 ].ColorIndex = 16;
csa[ 3 ].ColorIndex = 24;
csa[ 17 ].ColorIndex = 28;
csa[ 19 ].ColorIndex = 31;
for( wIdx = 0; wIdx < 32; wIdx++ )
laPens[ wIdx ] = csa[ wIdx ].ColorIndex;
wIdx = -1;
scr = OpenScreenTags( NULL,
SA_Depth, 5,
SA_DisplayID, LORES_KEY,
SA_Title, (LONG)"Fractal Mountains",
SA_Colors, (LONG)&csa,
SA_Pens, (LONG)&wIdx,
TAG_DONE );
if( !scr )
goto fail;
lScrTag = WA_CustomScreen;
}
wMaxX = scr->Width;
wMaxY = scr->Height;
if( !(visualInfo = GetVisualInfoA( scr, NULL )) )
goto fail;
pwinMain = OpenWindowTags( NULL,
WA_Width, 320,
WA_Height, 256,
WA_AutoAdjust, TRUE,
WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_MENUPICK | IDCMP_NEWSIZE
| IDCMP_RAWKEY | IDCMP_VANILLAKEY
| IDCMP_GADGETUP | IDCMP_GADGETDOWN | IDCMP_INTUITICKS,
WA_Flags, WFLG_DEPTHGADGET | WFLG_DRAGBAR | WFLG_CLOSEGADGET
| WFLG_SIZEGADGET | WFLG_SIZEBBOTTOM | WFLG_SIZEBRIGHT
| WFLG_NEWLOOKMENUS,
WA_Activate, TRUE,
WA_ScreenTitle, (LONG)"Fractal Mountains",
lScrTag, (LONG)scr,
TAG_DONE );
if( !pwinMain )
goto fail;
WindowLimits( pwinMain, 160, 160, -1L, -1L );
SetFont( pwinMain->RPort, defFont );
/* Build the menus: */
menu = CreateMenus( nmaMenu, TAG_DONE );
if( !menu )
goto fail;
LayoutMenus( menu, visualInfo,
GTMN_NewLookMenus, TRUE,
TAG_DONE );
SetMenuStrip( pwinMain, menu );
/* Attach the Gadgets: */
gadCmd.LeftEdge = -pwinMain->BorderRight + 3;
gadCmd.TopEdge = pwinMain->BorderTop + 1;
gadCmd.Width = pwinMain->BorderRight - 4;
gadCmd.Height = pwinMain->BorderBottom - 2;
gadRise.LeftEdge = -pwinMain->BorderRight + 3;
gadRise.TopEdge = pwinMain->BorderTop + pwinMain->BorderBottom;
gadRise.Width = pwinMain->BorderRight - 4;
gadRise.Height = -(pwinMain->BorderTop + 2*pwinMain->BorderBottom);
gadSpin.LeftEdge = 3;
gadSpin.TopEdge = -pwinMain->BorderBottom + 3;
gadSpin.Width = -(pwinMain->BorderRight + 3);
gadSpin.Height = pwinMain->BorderBottom - 4;
AddGadget( pwinMain, &gadRise, -1 );
AddGadget( pwinMain, &gadSpin, -1 );
AddGadget( pwinMain, &gadCmd, -1 );
RefreshGadgets( &gadRise, pwinMain, NULL );
/* Attach an AreaInfo and a TmpRas to our RastPort, so we can do */
/* area fill operations on it. */
ras = AllocRaster( wMaxX, wMaxY );
if( !ras )
goto fail;
InitTmpRas( &tras, ras, RASSIZE( wMaxX, wMaxY ) );
InitArea( &ari, waArBuf, AREA_BYTES/5 );
pwinMain->RPort->TmpRas = &tras;
pwinMain->RPort->AreaInfo = &ari;
return TRUE;
fail:
DestroyGui();
return FALSE;
}
/*------------------------------------------------------------------------*\
Tear down the window and close (or release) the screen it's on.
Closes the child window first, which shares some of our resources
(screen and menus).
\*------------------------------------------------------------------------*/
VOID DestroyGui()
{
WORD wColor;
if( pwinMain )
{
ClearMenuStrip( pwinMain );
CloseWindow( pwinMain );
}
pwinMain = NULL;
if( ras )
FreeRaster( ras, wMaxX, wMaxY );
if( menu )
FreeMenus( menu );
menu = NULL;
if( visualInfo )
FreeVisualInfo( visualInfo );
visualInfo = NULL;
if( scr )
if( fGfxV39 )
{
UnlockPubScreen( NULL, scr );
for( wColor = 0; wColor < 32; wColor++ )
ReleasePen( scr->ViewPort.ColorMap, laPens[ wColor ] );
}
else
CloseScreen( scr );
scr = NULL;
}
/*------------------------------------------------------------------------*\
Disable input to the main window by putting up an invisible requester,
as shown in the RKRM example. Supply FALSE to enable input again.
If we have OS3.x, we will also set a busy pointer for the main window
while it is locked.
\*------------------------------------------------------------------------*/
VOID DisableMainWindow( BOOL fReally )
{
static struct Requester rq;
static BOOL fLocked = FALSE;
if( fReally && !fLocked )
{
InitRequester( &rq );
fLocked = Request( &rq, pwinMain );
if( fLocked & fIntV39 )
SetWindowPointer( pwinMain,
WA_BusyPointer, TRUE,
TAG_DONE );
}
if( !fReally && fLocked )
{
fLocked = FALSE;
EndRequest( &rq, pwinMain );
if( fIntV39 )
SetWindowPointer( pwinMain, TAG_DONE );
}
}
/*------------------------------------------------------------------------*\
Set up or clear a busy pointer for the main window.
Only works with OS3.x.
Use this instead of DisableMainWindow(), if you are still going to check
the window's message port during whatever you're doing.
\*------------------------------------------------------------------------*/
VOID SnoozeMainWindow( BOOL fReally )
{
if( fIntV39 )
SetWindowPointer( pwinMain,
!fReally ? TAG_DONE :
WA_BusyPointer, TRUE,
/*WA_PointerDelay, TRUE,*/
TAG_DONE );
}
/*------------------------------------------------------------------------*\
Open a window with some string gadgets and labels in it,
as described by the supplied MSR_ITEMs.
The window's initial position is specified by the IBox parameter, and
its final position is returned there, too. Note that the *height* of the
window is always calculated automatically.
The supplied screen must not be NULL.
In case the "requester" is cancelled, the supplied buffers will remain
unchanged and the return value is FALSE.
Note: This subroutine uses no global variables, so it might be useful
in other projects, too.
\*------------------------------------------------------------------------*/
VOID GadgetOnOff( struct Window *pwin, struct Gadget *pgad )
/* Put in a separate function to work around a silly "spilled */
/* register" error from GCC. */
{
GT_SetGadgetAttrs( pgad, pwin, NULL,
GA_Disabled, TRUE,
TAG_DONE );
GT_SetGadgetAttrs( pgad, pwin, NULL,
GA_Disabled, FALSE,
TAG_DONE );
}
BOOL MultiStringRequest( struct Screen *pscr, BOOL fPubScreen, struct IBox *pib,
STRPTR strHail, STRPTR strOk, STRPTR strCancel,
WORD wItems, MSR_ITEM *pmi )
{
struct Window *pwin = NULL;
struct NewGadget ng;
struct Gadget *pgad, *pgadRoot = NULL;
struct Gadget *pgadFirst = NULL, *pgadLast;
struct IntuiMessage *intuiMsg;
struct VisualInfo *pvi;
char caBuf[ 20 ];
WORD wFontY = pscr->Font->ta_YSize;
WORD wStrGadH = wFontY + 8, wButtonH = wFontY + 4;
WORD wStrSepH = wFontY / 2, wButSepH = wFontY;
WORD wTopH = wFontY / 2, wBottomH = wFontY / 2;
WORD wBorderW = wFontY / 2, wLabSepW = wFontY / 2;
WORD wButtonW, wLabelW, wTemp, wIdx;
STRPTR str;
BOOL fQuit = FALSE, fResult = FALSE;
enum { IDC_STATIC, IDC_OK, IDC_CANCEL, IDC_INPUT };
assert( pscr != NULL );
if( !(pvi = GetVisualInfoA( pscr, NULL )) )
return FALSE;
pwin = OpenWindowTags( NULL,
WA_Left, pib->Left,
WA_Top, pib->Top,
WA_Width, pib->Width,
WA_InnerHeight, wTopH + wItems*(wStrGadH + wStrSepH) - wStrSepH
+ wButSepH + wButtonH + wBottomH,
WA_AutoAdjust, TRUE,
WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_RAWKEY | IDCMP_VANILLAKEY
| STRINGIDCMP,
WA_Flags, WFLG_DEPTHGADGET | WFLG_DRAGBAR | WFLG_CLOSEGADGET,
WA_Activate, TRUE,
WA_Title, (LONG)strHail,
!fPubScreen ? WA_CustomScreen :
WA_PubScreen, (LONG)pscr,
TAG_DONE );
if( pwin == NULL )
goto fail;
/* Determine the width of the buttons and the labels. */
str = strCancel;
wButtonW = TextLength( pwin->RPort, str, strlen( str ) );
str = strOk;
wTemp = TextLength( pwin->RPort, str, strlen( str ) );
if( wButtonW < wTemp )
wButtonW = wTemp;
wButtonW = 3 * wButtonW / 2;
wLabelW = 0;
for( wIdx = 0; wIdx < wItems; wIdx++ )
{
str = pmi[ wIdx ].strLabel;
if( str != NULL )
{
wTemp = TextLength( pwin->RPort, str, strlen( str ) );
if( wLabelW < wTemp )
wLabelW = wTemp;
}
}
if( wLabelW != 0 )
wLabelW += wLabSepW;
/* Add some gadtools gadgets. */
pgad = CreateContext( &pgadRoot );
/* string gadgets */
ng.ng_VisualInfo = pvi;
ng.ng_TextAttr = pscr->Font;
ng.ng_Flags = 0;
ng.ng_LeftEdge = pwin->BorderLeft + wBorderW + wLabelW;
ng.ng_Width = pwin->Width - pwin->BorderRight - wBorderW - ng.ng_LeftEdge;
ng.ng_TopEdge = pwin->BorderTop + wTopH;
ng.ng_Height = wStrGadH;
ng.ng_GadgetText = NULL;
for( wIdx = 0; wIdx < wItems; wIdx++ )
{
ng.ng_GadgetID = IDC_INPUT + wIdx;
switch( pmi[ wIdx ].wType )
{
case MSRT_STRING:
pgad = CreateGadget( STRING_KIND, pgad, &ng,
GTST_String, (LONG)pmi[ wIdx ].val.strBuf,
GTST_MaxChars, pmi[ wIdx ].wBufSize,
TAG_DONE );
break;
case MSRT_LONG:
pgad = CreateGadget( INTEGER_KIND, pgad, &ng,
GTIN_Number, pmi[ wIdx ].val.lVal,
TAG_DONE );
break;
case MSRT_FLOAT:
sprintf( caBuf, "%g", pmi[ wIdx ].val.flVal );
pgad = CreateGadget( STRING_KIND, pgad, &ng,
GTST_String, (LONG)caBuf,
GTST_MaxChars, sizeof( caBuf ),
TAG_DONE );
break;
default: /* invalid entry type */
assert( FALSE );
}
pmi[ wIdx ].pgad = pgad;
ng.ng_TopEdge += wStrGadH + wStrSepH;
if( pgadFirst == NULL )
pgadFirst = pgad;
}
pgadLast = pgad;
/* OK and Cancel buttons */
ng.ng_Width = wButtonW;
ng.ng_TopEdge += wButSepH - wStrSepH;
ng.ng_Height = wButtonH;
ng.ng_GadgetText = strOk;
ng.ng_GadgetID = IDC_OK;
pgad = CreateGadget( BUTTON_KIND, pgad, &ng, TAG_DONE );
ng.ng_LeftEdge = pwin->Width - pwin->BorderRight - wBorderW - wButtonW;
ng.ng_GadgetText = strCancel;
ng.ng_GadgetID = IDC_CANCEL;
pgad = CreateGadget( BUTTON_KIND, pgad, &ng, TAG_DONE );
if( pgad == NULL )
goto fail;
AddGList( pwin, pgadRoot, -1, -1, NULL );
RefreshGList( pgadRoot, pwin, NULL, -1 );
GT_RefreshWindow( pwin, NULL );
ActivateGadget( pgadFirst, pwin, NULL );
while( !fQuit )
{
intuiMsg = GT_GetIMsg( pwin->UserPort );
if( !intuiMsg )
{
WaitPort( pwin->UserPort );
continue;
}
switch( intuiMsg->Class )
{
case IDCMP_GADGETUP:
pgad = intuiMsg->IAddress;
if( pgad == pgadLast ) /* msg from the last string gadget */
{
/* Hitting enter in the last string gadget implies */
/* closing the requester. Shift-Enter however should */
/* enable the user to simply deactivate any string */
/* gadgets (so he can type shortcuts to other gadgets, */
/* maybe ESC in particular). */
if( (intuiMsg->Qualifier
& (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)) != 0 )
break;
else if( intuiMsg->Code == 0 )
{
fResult = TRUE;
fQuit = TRUE;
}
else if( intuiMsg->Code == 9 )
{
/* We don't want TAB to cycle from the last to */
/* the first of our string gadgets. */
/* To prevent this, we simply deactivate the */
/* first string gadget, and the only legal way to */
/* do this for a gadtools gadget is by disabling */
/* and reenabling it. */
GadgetOnOff( pwin, pgadFirst );
}
else
/* On systems with MCP or such installed, we */
/* will get here in reply to ESC. */
fQuit = TRUE;
}
else switch( pgad->GadgetID )
{
case IDC_OK:
fResult = TRUE;
fQuit = TRUE;
break;
case IDC_CANCEL:
fQuit = TRUE;
break;
}
break;
case IDCMP_VANILLAKEY:
switch( intuiMsg->Code )
{
case 9: /* TAB reenables the string gadget gang. */
ActivateGadget( pgadFirst, pwin, NULL );
break;
case 13:
fResult = TRUE;
fQuit = TRUE;
break;
case 27:
fQuit = TRUE;
break;
}
break;
case IDCMP_CLOSEWINDOW:
fQuit = TRUE;
break;
}
GT_ReplyIMsg( intuiMsg );
}
if( fResult )
/* Copy the contents of the string gadgets. */
for( wIdx = 0; wIdx < wItems; wIdx++ )
{
str = ((struct StringInfo *)pmi[ wIdx ].pgad->SpecialInfo)->Buffer;
switch( pmi[ wIdx ].wType )
{
case MSRT_STRING:
strcpy( pmi[ wIdx ].val.strBuf, str );
break;
case MSRT_LONG:
pmi[ wIdx ].val.lVal = atol( str );
break;
case MSRT_FLOAT:
pmi[ wIdx ].val.flVal = atof( str );
break;
}
}
pib->Left = pwin->LeftEdge; /* Remember window position */
pib->Top = pwin->TopEdge;
pib->Width = pwin->Width;
pib->Height = pwin->Height;
fail:
if( pwin )
CloseWindow( pwin );
if( pgadRoot )
FreeGadgets( pgadRoot );
if( pvi )
FreeVisualInfo( pvi );
return fResult;
}
/*------------------------------------------------------------------------*\
Open a window with a string gadget in it and read a string.
In case the "requester" is cancelled, the supplied buffer will remain
unchanged.
\*------------------------------------------------------------------------*/
BOOL StringRequest( STRPTR strHail, STRPTR strBuf, WORD wSize )
{
struct IBox ib;
MSR_ITEM mi;
BOOL fResult;
mi.strLabel = NULL;
mi.wType = MSRT_STRING;
mi.val.strBuf = strBuf;
mi.wBufSize = wSize;
/* open relative to main window */
ib.Left = pwinMain->LeftEdge + 50;
ib.Top = pwinMain->TopEdge + 50;
ib.Width = pwinMain->Width - 100;
DisableMainWindow( TRUE );
fResult = MultiStringRequest( scr, fGfxV39, &ib, strHail,
"OK", "Cancel", 1, &mi );
DisableMainWindow( FALSE );
return fResult;
}